home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / music.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  16.9 KB  |  704 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)music.c    3.1    93/05/25    */
  2. /*     Copyright (c) 1989 by Jean-Christophe Collet */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /*
  6.  * This file contains the different functions designed to manipulate the
  7.  * musical instruments and their various effects.
  8.  *
  9.  * Actually the list of instruments / effects is :
  10.  *
  11.  * (wooden) flute    may calm snakes if player has enough dexterity
  12.  * magic flute        may put monsters to sleep:  area of effect depends
  13.  *            on player level.
  14.  * (tooled) horn    Will awaken monsters:  area of effect depends on player
  15.  *            level.  May also scare monsters.
  16.  * fire horn        Acts like a wand of fire.
  17.  * frost horn        Acts like a wand of cold.
  18.  * bugle        Will awaken soldiers (if any):  area of effect depends
  19.  *            on player level.
  20.  * (wooden) harp    May calm nymph if player has enough dexterity.
  21.  * magic harp        Charm monsters:  area of effect depends on player
  22.  *            level.
  23.  * (leather) drum    Will awaken monsters like the horn.
  24.  * drum of earthquake    Will initiate an earthquake whose intensity depends
  25.  *            on player level.  That is, it creates random pits
  26.  *            called here chasms.
  27.  */
  28.  
  29. #include "hack.h"
  30.  
  31. static void FDECL(awaken_monsters,(int));
  32. static void FDECL(put_monsters_to_sleep,(int));
  33. static void FDECL(charm_snakes,(int));
  34. static void FDECL(calm_nymphs,(int));
  35. static void FDECL(charm_monsters,(int));
  36. static void FDECL(do_earthquake,(int));
  37. static int FDECL(do_improvisation,(struct obj *));
  38.  
  39. #ifdef UNIX386MUSIC
  40. static int NDECL(atconsole);
  41. static void FDECL(speaker,(struct obj *,char *));
  42. #endif
  43. #ifdef VPIX_MUSIC
  44. extern int sco_flag_console;    /* will need changing if not _M_UNIX */
  45. static void NDECL(playinit);
  46. static void FDECL(playstring, (char *,size_t));
  47. static void FDECL(speaker,(struct obj *,char *));
  48. #endif
  49.  
  50. #ifdef AMIGA
  51. void FDECL( amii_speaker, ( struct obj *, char *, int ) );
  52. #endif
  53.  
  54. /*
  55.  * Wake every monster in range...
  56.  */
  57.  
  58. static void
  59. awaken_monsters(distance)
  60. int distance;
  61. {
  62.     register struct monst *mtmp = fmon;
  63.     register int distm;
  64.  
  65.     while(mtmp) {
  66.         distm = distu(mtmp->mx, mtmp->my);
  67.         if (distm < distance) {
  68.             mtmp->msleep = 0;
  69.             mtmp->mcanmove = 1;
  70.             mtmp->mfrozen = 0;
  71.             /* May scare some monsters */
  72.             if (distm < distance/3 &&
  73.                 !resist(mtmp, SCROLL_CLASS, 0, NOTELL))
  74.             mtmp->mflee = 1;
  75.         }
  76.         mtmp = mtmp->nmon;
  77.     }
  78. }
  79.  
  80. /*
  81.  * Make monsters fall asleep.  Note that they may resist the spell.
  82.  */
  83.  
  84. static void
  85. put_monsters_to_sleep(distance)
  86. int distance;
  87. {
  88.     register struct monst *mtmp = fmon;
  89.  
  90.     while(mtmp) {
  91.         if (distu(mtmp->mx, mtmp->my) < distance &&
  92.             !resist(mtmp, WAND_CLASS, 0, NOTELL)) {
  93.             register int min_sleep = d(10,10);
  94.             /* 10d10 turns + wake_nearby() to rouse */
  95.             mtmp->msleep = 1;
  96.             mtmp->mcanmove = 0;
  97.             if ((int)mtmp->mfrozen < min_sleep)
  98.             mtmp->mfrozen = min_sleep;
  99.         }
  100.         mtmp = mtmp->nmon;
  101.     }
  102. }
  103.  
  104. /*
  105.  * Charm snakes in range.  Note that the snakes are NOT tamed.
  106.  */
  107.  
  108. static void
  109. charm_snakes(distance)
  110. int distance;
  111. {
  112.     register struct monst *mtmp = fmon;
  113.  
  114.     while (mtmp) {
  115.         if (mtmp->data->mlet == S_SNAKE &&
  116.             distu(mtmp->mx, mtmp->my) < distance) {
  117.             mtmp->mpeaceful = 1;
  118.             if (cansee(mtmp->mx, mtmp->my))
  119.                 pline(
  120.  "%s freezes and sways with the music, then seems quieter.", Monnam(mtmp));
  121.         }
  122.         mtmp = mtmp->nmon;
  123.     }
  124. }
  125.  
  126. /*
  127.  * Calm nymphs in range.
  128.  */
  129.  
  130. static void
  131. calm_nymphs(distance)
  132. int distance;
  133. {
  134.     register struct monst *mtmp = fmon;
  135.  
  136.     while (mtmp) {
  137.         if (mtmp->data->mlet == S_NYMPH &&
  138.             distu(mtmp->mx, mtmp->my) < distance) {
  139.             mtmp->mpeaceful = 1;
  140.             if (cansee(mtmp->mx, mtmp->my))
  141.                 pline(
  142.  "%s listens cheerfully to the music, then seems quieter.", Monnam(mtmp));
  143.         }
  144.         mtmp = mtmp->nmon;
  145.     }
  146. }
  147.  
  148. /* Awake only soldiers of the level. */
  149.  
  150. void
  151. awaken_soldiers()
  152. {
  153. #ifdef ARMY
  154.     register struct monst *mtmp = fmon;
  155.  
  156.     while(mtmp) {
  157.         if (is_mercenary(mtmp->data) && mtmp->data != &mons[PM_GUARD]) {
  158.         mtmp->mpeaceful = mtmp->msleep = mtmp->mfrozen = 0;
  159.         mtmp->mcanmove = 1;
  160.         if (canseemon(mtmp))
  161.             pline("%s is now ready for battle!", Monnam(mtmp));
  162.         else
  163.             Norep("You hear the rattle of battle gear being readied.");
  164.         }
  165.         mtmp = mtmp->nmon;
  166.     }
  167. #endif /* ARMY */
  168. }
  169.  
  170. /* Charm monsters in range.  Note that they may resist the spell. */
  171.  
  172. static void
  173. charm_monsters(distance)
  174. int distance;
  175. {
  176.     register struct monst *mtmp = fmon, *mtmp2;
  177.  
  178.     while(mtmp) {
  179.         mtmp2 = mtmp->nmon;
  180.         if (distu(mtmp->mx, mtmp->my) <= distance)
  181.             if(!resist(mtmp, SCROLL_CLASS, 0, NOTELL))
  182.             (void) tamedog(mtmp, (struct obj *) 0);
  183.         mtmp = mtmp2;
  184.     }
  185.  
  186. }
  187.  
  188. /* Generate earthquake :-) of desired force.
  189.  * That is:  create random chasms (pits).
  190.  */
  191.  
  192. static void
  193. do_earthquake(force)
  194. int force;
  195. {
  196.     register int x,y;
  197.     struct monst *mtmp;
  198.     struct obj *otmp;
  199.     struct trap *chasm;
  200.     int start_x, start_y, end_x, end_y;
  201.  
  202.     start_x = u.ux - (force * 2);
  203.     start_y = u.uy - (force * 2);
  204.     end_x = u.ux + (force * 2);
  205.     end_y = u.uy + (force * 2);
  206.     if (start_x < 1) start_x = 1;
  207.     if (start_y < 1) start_y = 1;
  208.     if (end_x >= COLNO) end_x = COLNO - 1;
  209.     if (end_y >= ROWNO) end_y = ROWNO - 1;
  210.     for (x=start_x; x<=end_x; x++) for (y=start_y; y<=end_y; y++) {
  211.         if ((mtmp = m_at(x,y)) != 0) {
  212.         wakeup(mtmp);    /* peaceful monster will become hostile */
  213.         if (mtmp->mundetected && is_hider(mtmp->data)) {
  214.             mtmp->mundetected = 0;
  215.             if (cansee(x,y))
  216.             pline("%s is shaken loose from the ceiling!",
  217.                                 Amonnam(mtmp));
  218.             else
  219.             You("hear a thumping sound.");
  220.             if (x==u.ux && y==u.uy)
  221.             You("easily dodge the falling %s.",
  222.                                 mon_nam(mtmp));
  223.             newsym(x,y);
  224.         }
  225.         }
  226.         if (!rn2(14 - force)) switch (levl[x][y].typ) {
  227.           case FOUNTAIN : /* Make the fountain disappear */
  228.             if (cansee(x,y))
  229.                 pline("The fountain falls into a chasm.");
  230.             goto do_pit;
  231. #ifdef SINKS
  232.           case SINK :
  233.             if (cansee(x,y))
  234.                 pline("The kitchen sink falls into a chasm.");
  235.             goto do_pit;
  236. #endif
  237.           case ALTAR :
  238.             if (cansee(x,y))
  239.                 pline("The altar falls into a chasm.");
  240.             goto do_pit;
  241.           case THRONE :
  242.             if (cansee(x,y))
  243.                 pline("The throne falls into a chasm.");
  244.             /* Falls into next case */
  245.           case ROOM :
  246.           case CORR : /* Try to make a pit */
  247. do_pit:            chasm = maketrap(x,y,PIT);
  248.             if (!chasm) break;    /* no pit if portal at that location */
  249.             chasm->tseen = 1;
  250.  
  251.             levl[x][y].doormask = 0;
  252.  
  253.             mtmp = m_at(x,y);
  254.  
  255.             if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
  256.             if (cansee(x, y))
  257.                pline("KADOOM! The boulder falls into a chasm%s!",
  258.                   ((x == u.ux) && (y == u.uy)) ? " below you" : "");
  259.             if (mtmp)
  260.                 mtmp->mtrapped = 0;
  261.             freeobj(otmp);
  262.             (void) flooreffects(otmp, x, y, "");
  263.             break;
  264.             }
  265.  
  266.             /* We have to check whether monsters or player
  267.                falls in a chasm... */
  268.  
  269.             if (mtmp) {
  270.             if(!is_flyer(mtmp->data) && !is_clinger(mtmp->data)) {
  271.                 mtmp->mtrapped = 1;
  272.                 if(cansee(x,y))
  273.                 pline("%s falls into a chasm!", Monnam(mtmp));
  274.                 else if (flags.soundok && humanoid(mtmp->data))
  275.                 You("hear a scream!");
  276. #ifdef MUSE
  277.                 mselftouch(mtmp, "Falling, ", TRUE);
  278.                 if (mtmp->mhp > 0)
  279. #endif
  280.                 if ((mtmp->mhp -= rnd(6)) <= 0) {
  281.                 if(!cansee(x,y))
  282.                     pline("It is destroyed!");
  283.                 else {
  284.                     You("destroy %s!", mtmp->mtame ?
  285.                     x_monnam(mtmp, 0, "poor", 0) :
  286.                     mon_nam(mtmp));
  287.                 }
  288.                 xkilled(mtmp,0);
  289.                 }
  290.             }
  291.             } else if (x == u.ux && y == u.uy) {
  292.                 if (Levitation
  293. #ifdef POLYSELF
  294.                 || is_flyer(uasmon) || is_clinger(uasmon)
  295. #endif
  296.                 ) {
  297.                     pline("A chasm opens up under you!");
  298.                     You("don't fall in!");
  299.                 } else {
  300.                     You("fall into a chasm!");
  301.                     u.utrap = rn1(6,2);
  302.                     u.utraptype = TT_PIT;
  303.                     losehp(rnd(6),"fell into a chasm",
  304.                     NO_KILLER_PREFIX);
  305.                     selftouch("Falling, you");
  306.                 }
  307.             } else newsym(x,y);
  308.             break;
  309.           case DOOR : /* Make the door collapse */
  310.             if (levl[x][y].doormask == D_NODOOR) break;
  311.             if (cansee(x,y))
  312.             pline("The door collapses.");
  313.             levl[x][y].doormask = D_NODOOR;
  314.             newsym(x,y);
  315.             break;
  316.         }
  317.     }
  318. }
  319.  
  320. /*
  321.  * The player is trying to extract something from his/her instrument.
  322.  */
  323.  
  324. static int
  325. do_improvisation(instr)
  326. struct obj *instr;
  327. {
  328.     int damage;
  329.  
  330. #ifdef MAC
  331.     mac_speaker ( instr , "C" ) ;
  332. #endif
  333. #ifdef AMIGA
  334.     amii_speaker ( instr , "Cw", AMII_OKAY_VOLUME ) ;
  335. #endif
  336. #ifdef VPIX_MUSIC
  337.     if (sco_flag_console)
  338.         speaker(instr, "C");
  339. #endif
  340.     if (Confusion)
  341.       pline("What you produce is quite far from music...");
  342.     else
  343.       You("start playing %s.", the(xname(instr)));
  344.     switch (instr->otyp) {
  345.           case WOODEN_FLUTE:    /* May charm snakes */
  346.         if (rn2(ACURR(A_DEX)) + u.ulevel > 25)
  347.           charm_snakes((int)u.ulevel*3);
  348.         exercise(A_DEX, TRUE);
  349.         break;
  350.           case MAGIC_FLUTE: /* Make monster fall asleep */
  351.         if (instr->spe > 0) {
  352.             instr->spe--;
  353.             check_unpaid(instr);
  354.             You("produce soft music.");
  355.             put_monsters_to_sleep((int)u.ulevel*5);
  356.         }
  357.         exercise(A_DEX, TRUE);
  358.         break;
  359.           case TOOLED_HORN:    /* Awaken monsters or scare monsters */
  360.         You("produce a frightful, grave sound.");
  361.         awaken_monsters((int)u.ulevel*30);
  362.         exercise(A_WIS, FALSE);
  363.         break;
  364.           case FROST_HORN:    /* Idem wand of cold */
  365.           case FIRE_HORN:    /* Idem wand of fire */
  366.         if (instr->spe > 0) {
  367.             instr->spe--;
  368.             check_unpaid(instr);
  369.             if (!getdir(NULL)) {
  370.                 if (!Blind)
  371.                     pline("%s glows then fades.",
  372.                       The(xname(instr)));
  373.             } else {
  374.                 if (!u.dx && !u.dy && !u.dz) {
  375.                     if((damage = zapyourself(instr)))
  376.                       losehp(damage,
  377.         self_pronoun("using a magical horn on %sself", "him"),
  378.                       NO_KILLER_PREFIX);
  379.                     makeknown(instr->otyp);
  380.                     return(2);
  381.                 }
  382.                 buzz((instr->otyp == FROST_HORN) ? AD_COLD-1 : AD_FIRE-1, rn1(6,6), u.ux, u.uy, u.dx, u.dy);
  383.                 makeknown(instr->otyp);
  384.                 return(2);
  385.             }
  386.         }
  387.         break;
  388.           case BUGLE:    /* Awaken & attract soldiers */
  389.         You("extract a loud noise from %s.", the(xname(instr)));
  390.         awaken_soldiers();
  391.         exercise(A_WIS, FALSE);
  392.         break;
  393.           case WOODEN_HARP:    /* May calm Nymph */
  394.         if (rn2(ACURR(A_DEX)) + u.ulevel > 25)
  395.           calm_nymphs((int)u.ulevel*3);
  396.         exercise(A_DEX, TRUE);
  397.         break;
  398.           case MAGIC_HARP:    /* Charm monsters */
  399.         if (instr->spe > 0) {
  400.             instr->spe--;
  401.             check_unpaid(instr);
  402.             pline("%s produces very attractive music.",
  403.                   The(xname(instr)));
  404.             charm_monsters(((int)u.ulevel - 1) / 3 + 1);
  405.         }
  406.         exercise(A_DEX, TRUE);
  407.         break;
  408.           case LEATHER_DRUM:    /* Awaken monsters */
  409.         You("beat a deafening row!");
  410.         awaken_monsters((int)u.ulevel * 40);
  411.         exercise(A_WIS, FALSE);
  412.         break;
  413.           case DRUM_OF_EARTHQUAKE:    /* create several pits */
  414.         if (instr->spe > 0) {
  415.             instr->spe--;
  416.             check_unpaid(instr);
  417.             You("produce a heavy, thunderous rolling!");
  418.             pline("The entire dungeon is shaking around you!");
  419.             do_earthquake(((int)u.ulevel - 1) / 3 + 1);
  420.             /* shake up monsters in a much larger radius... */
  421.             awaken_monsters(ROWNO * COLNO);
  422.             makeknown(DRUM_OF_EARTHQUAKE);
  423.         }
  424.         break;
  425.           default:
  426.         impossible("What a weird instrument (%d)!",instr->otyp);
  427.         break;
  428.     }
  429.     return (2);        /* That takes time */
  430. }
  431.  
  432. /*
  433.  * So you want music...
  434.  */
  435.  
  436. int
  437. do_play_instrument(instr)
  438. struct obj *instr;
  439. {
  440.     char buf[BUFSZ], c = 'y';
  441. #ifndef    AMIGA
  442.     char *s;
  443. #endif
  444.     int x,y;
  445.     boolean ok;
  446.  
  447.     if (Underwater) {
  448.     You("can't play music underwater!");
  449.     return(0);
  450.     }
  451.     if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) {
  452.     c = yn("Improvise?");
  453.     }
  454.     if (c == 'n') {
  455.     if (u.uevent.uheard_tune == 2 && yn("Play the passtune?") == 'y')
  456.         Strcpy(buf, tune);
  457.     else
  458.         getlin("What tune are you playing? [what 5 notes]", buf);
  459. #ifndef    AMIGA
  460.     /* The AMIGA supports two octaves of notes */
  461.     for (s=buf; *s; s++) *s = highc(*s);
  462. #endif
  463.     You("extract a strange sound from %s!", the(xname(instr)));
  464. #ifdef UNIX386MUSIC
  465.     /* if user is at the console, play through the console speaker */
  466.     if (atconsole())
  467.         speaker(instr, buf);
  468. #endif
  469. #ifdef VPIX_MUSIC
  470.     if (sco_flag_console)
  471.         speaker(instr, buf);
  472. #endif
  473. #ifdef MAC
  474.     mac_speaker ( instr , buf ) ;
  475. #endif
  476. #ifdef AMIGA
  477.     {
  478.         char nbuf[ 20 ];
  479.         int i;
  480.         for( i = 0; buf[i] && i < 5; ++i )
  481.         {
  482.             nbuf[ i*2 ] = buf[ i ];
  483.             nbuf[ (i*2)+1 ] = 'h';
  484.         }
  485.         nbuf[ i*2 ] = 0;
  486.         amii_speaker ( instr , nbuf, AMII_OKAY_VOLUME ) ;
  487.     }
  488. #endif
  489.     /* Check if there was the Stronghold drawbridge near
  490.      * and if the tune conforms to what we're waiting for.
  491.      */
  492.     if(Is_stronghold(&u.uz)) {
  493.         exercise(A_WIS, TRUE);        /* just for trying */
  494.         if(!strcmp(buf,tune)) {
  495.         /* Search for the drawbridge */
  496.         for(y=u.uy-1; y<=u.uy+1; y++)
  497.             for(x=u.ux-1;x<=u.ux+1;x++)
  498.             if(isok(x,y))
  499.             if(find_drawbridge(&x,&y)) {
  500.                 if(levl[x][y].typ == DRAWBRIDGE_DOWN)
  501.                 close_drawbridge(x,y);
  502.                 else
  503.                 open_drawbridge(x,y);
  504.                 return 0;
  505.             }
  506.         } else if(flags.soundok) {
  507.         if (u.uevent.uheard_tune < 1) u.uevent.uheard_tune = 1;
  508.         /* Okay, it wasn't the right tune, but perhaps
  509.          * we can give the player some hints like in the
  510.          * Mastermind game */
  511.         ok = FALSE;
  512.         for(y = u.uy-1; y <= u.uy+1 && !ok; y++)
  513.             for(x = u.ux-1; x <= u.ux+1 && !ok; x++)
  514.             if(isok(x,y))
  515.             if(IS_DRAWBRIDGE(levl[x][y].typ) ||
  516.                is_drawbridge_wall(x,y) >= 0)
  517.                 ok = TRUE;
  518.         if(ok) { /* There is a drawbridge near */
  519.             int tumblers, gears;
  520.             boolean matched[5];
  521.  
  522.             tumblers = gears = 0;
  523.             for(x=0; x < 5; x++)
  524.             matched[x] = FALSE;
  525.  
  526.             for(x=0; x < (int)strlen(buf); x++)
  527.             if(x < 5) {
  528.                 if(buf[x] == tune[x]) {
  529.                 gears++;
  530.                 matched[x] = TRUE;
  531.                 } else
  532.                 for(y=0; y < 5; y++)
  533.                     if(!matched[y] &&
  534.                        buf[x] == tune[y] &&
  535.                        buf[y] != tune[y]) {
  536.                     tumblers++;
  537.                     matched[y] = TRUE;
  538.                     break;
  539.                     }
  540.             }
  541.             if(tumblers)
  542.             if(gears)
  543.                 You("hear %d tumbler%s click and %d gear%s turn.",
  544.                 tumblers, plur(tumblers), gears, plur(gears));
  545.             else
  546.                 You("hear %d tumbler%s click.",
  547.                 tumblers, plur(tumblers));
  548.             else if(gears) {
  549.             You("hear %d gear%s turn.", gears, plur(gears));
  550.             if (gears == 5) u.uevent.uheard_tune = 2;
  551.             }
  552.         }
  553.         }
  554.       }
  555.     return 1;
  556.     } else
  557.         return do_improvisation(instr);
  558. }
  559.  
  560. #ifdef UNIX386MUSIC
  561. /*
  562.  * Play audible music on the machine's speaker if appropriate.
  563.  */
  564.  
  565. static int
  566. atconsole()
  567. {
  568.     /*
  569.      * Kluge alert: This code assumes that your [34]86 has no X terminals
  570.      * attached and that the console tty type is AT386 (this is always true
  571.      * under AT&T UNIX for these boxen). The theory here is that your remote
  572.      * ttys will have terminal type `ansi' or something else other than
  573.      * `AT386' or `xterm'. We'd like to do better than this, but testing
  574.      * to see if we're running on the console physical terminal is quite
  575.      * difficult given the presence of virtual consoles and other modern
  576.      * UNIX impedimenta...
  577.      */
  578.     char    *termtype = getenv("TERM");
  579.  
  580.      return(!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
  581. }
  582.  
  583. static void
  584. speaker(instr, buf)
  585. struct obj *instr;
  586. char    *buf;
  587. {
  588.     /*
  589.      * For this to work, you need to have installed the PD speaker-control
  590.      * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
  591.      * posted to comp.sources.unix in Feb 1990.  A copy should be included
  592.      * with your nethack distribution.
  593.      */
  594.     int    fd;
  595.  
  596.     if ((fd = open("/dev/speaker", 1)) != -1)
  597.     {
  598.     /* send a prefix to modify instrumental `timbre' */
  599.     switch (instr->otyp)
  600.     {
  601.     case WOODEN_FLUTE:
  602.     case MAGIC_FLUTE:
  603.         (void) write(fd, ">ol", 1); /* up one octave & lock */
  604.         break;
  605.     case TOOLED_HORN:
  606.     case FROST_HORN:
  607.     case FIRE_HORN:
  608.         (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
  609.         break;
  610.     case BUGLE:
  611.         (void) write(fd, "ol", 2); /* octave lock */
  612.         break;
  613.     case WOODEN_HARP:
  614.     case MAGIC_HARP:
  615.         (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
  616.         break;
  617.     }
  618.     (void) write(fd, buf, strlen(buf));
  619.     (void) close(fd);
  620.     }
  621. }
  622. #endif /* UNIX386MUSIC */
  623.  
  624. #ifdef VPIX_MUSIC
  625.  
  626. # if 0
  627. #include <sys/types.h>
  628. #include <sys/console.h>
  629. #include <sys/vtkd.h>
  630. # else
  631. #define KIOC ('K' << 8)
  632. #define KDMKTONE (KIOC | 8)
  633. # endif
  634.  
  635. #define noDEBUG
  636.  
  637. #include "interp.c"    /* from snd86unx.shr */
  638.  
  639. static void tone(hz, ticks)
  640. /* emit tone of frequency hz for given number of ticks */
  641. unsigned int hz, ticks;
  642. {
  643.     ioctl(0,KDMKTONE,hz|((ticks*10)<<16));
  644. # ifdef DEBUG
  645.     printf("TONE: %6d %6d\n",hz,ticks * 10);
  646. # endif
  647.     nap(ticks * 10);
  648. }
  649.  
  650.  
  651. static void rest(ticks)
  652. /* rest for given number of ticks */
  653. int    ticks;
  654. {
  655.     nap(ticks * 10);
  656. # ifdef DEBUG
  657.     printf("REST:        %6d\n",ticks * 10);
  658. # endif
  659. }
  660.  
  661.  
  662. static void
  663. speaker(instr, buf)
  664. struct obj *instr;
  665. char    *buf;
  666. {
  667.     /* emit a prefix to modify instrumental `timbre' */
  668.     playinit();
  669.     switch (instr->otyp)
  670.     {
  671.     case WOODEN_FLUTE:
  672.     case MAGIC_FLUTE:
  673.         playstring(">ol", 1); /* up one octave & lock */
  674.         break;
  675.     case TOOLED_HORN:
  676.     case FROST_HORN:
  677.     case FIRE_HORN:
  678.         playstring("<<ol", 2); /* drop two octaves & lock */
  679.         break;
  680.     case BUGLE:
  681.         playstring("ol", 2); /* octave lock */
  682.         break;
  683.     case WOODEN_HARP:
  684.     case MAGIC_HARP:
  685.         playstring("l8mlol", 4); /* fast, legato, octave lock */
  686.         break;
  687.     }
  688.     playstring( buf, strlen(buf));
  689. }
  690.  
  691. # ifdef DEBUG
  692. main(argc,argv)
  693. char *argv[];
  694. {
  695.     if (argc == 2) {
  696.     playinit();
  697.     playstring(argv[1], strlen(argv[1]));
  698.     }
  699. }
  700. # endif
  701. #endif    /* VPIX_MUSIC */
  702.  
  703. /*music.c*/
  704.